﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

using LowLevelGraphics.ColorSpaces;

namespace LowLevelGraphics.Filter
{
    public delegate Color SortChannelsDelegate(Color color, bool _bAscending);
    //TODO: also interesting for ALL color spaces
    //TODO: SortChannels, this might also be extended to use PROCESSING_MODE
    /// <summary>
    /// Use this to sort the channel values
    /// 
    /// Choose between ascending and descending
    /// true = Ascending
    /// 
    /// 
    /// </summary>
    public class SortChannels : BaseImageFilter
    {
        protected bool m_bSortAscending = true;
        protected AbstractColorSpace m_AbstractColorSpace = null;
        protected SortChannelsDelegate m_SortChannelsDelegate = new SortChannelsDelegate(ColorFunctions.Sort);
        /// <summary>
        /// Default constructor
        /// Default is ascending
        /// </summary>
        public SortChannels()
            : this(true)
        {
        }

        /// <summary>
        /// Primary constructor to specify sorting mode directly
        /// </summary>
        /// <param name="_bAscending"></param>
        public SortChannels(bool _bAscending)
        {
            m_bSortAscending = _bAscending;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_bAscending"></param>
        public SortChannels(SortChannelsDelegate _sortChannelsDelegate, bool _bAscending)
            : this(_bAscending)
        {
            m_SortChannelsDelegate = _sortChannelsDelegate;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_sortChannelsDelegate"></param>
        public SortChannels(SortChannelsDelegate _sortChannelsDelegate)
        {
            m_SortChannelsDelegate = _sortChannelsDelegate;
            m_bSortAscending = true;
        }

        /// <summary>
        /// Gets or sets sortChannelDelegate
        /// </summary>
        public SortChannelsDelegate SortChannelsDelegate
        {
            get { return m_SortChannelsDelegate; }
            set { m_SortChannelsDelegate = value; }
        }

        /// <summary>
        /// used by clone to create a deep copy
        /// </summary>
        /// <param name="_sortChannels"></param>
        internal SortChannels(SortChannels _sortChannels)
        {
            this.m_bSortAscending = _sortChannels.m_bSortAscending;
            m_SortChannelsDelegate = _sortChannels.m_SortChannelsDelegate;
        }

        /// <summary>
        /// gets or sets sorting mode
        /// </summary>
        public bool Ascending
        {
            get { return m_bSortAscending; }
            set { m_bSortAscending = value; }
        }

        /// <summary>
        /// Executes this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            int x = 0;
            int y = 0;

            UnsafeBitmap bitmap = _bitmap;

            int nWidth = bitmap.Width;
            int nHeight = bitmap.Height;

            Color color = Color.Transparent;

            for (y = 0; y < nHeight; y++)
            {
                for (x = 0; x < nWidth; x++)
                {
                    color = bitmap.GetPixel(x, y);
                    color = m_SortChannelsDelegate(color, m_bSortAscending);
                    bitmap.SetPixel(x, y, color);
                }
            }

            return bitmap;
        }

        /// <summary>
        /// Used to create a deep copy
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new SortChannels(this);
        }
    }
}
